/*
package com.tianji.promotion.service.impl;

import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.exceptions.BizIllegalException;
import com.tianji.common.utils.StringUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.promotion.domain.po.Coupon;
import com.tianji.promotion.domain.po.ExchangeCode;
import com.tianji.promotion.domain.po.UserCoupon;
import com.tianji.promotion.enums.CouponStatus;
import com.tianji.promotion.enums.ExchangeCodeStatus;
import com.tianji.promotion.mapper.CouponMapper;
import com.tianji.promotion.mapper.UserCouponMapper;
import com.tianji.promotion.service.IExchangeCodeService;
import com.tianji.promotion.service.IUserCouponService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.promotion.utils.CodeUtil;
import com.tianji.promotion.utils.MyLock;
import com.tianji.promotion.utils.MyLockStrategy;
import com.tianji.promotion.utils.MyLockType;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

*/
/**
 * <p>
 * 用户领取优惠券的记录，是真正使用的优惠券信息 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-02-15
 *//*

@Service
@RequiredArgsConstructor
public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCoupon> implements IUserCouponService {

    private final CouponMapper couponMapper;
    private final IExchangeCodeService exchangeCodeService;
    private final RedissonClient redissonClient;

    */
/**
     * 领取优惠券
     * @param id
     *//*

    @Override
    //@Transactional
    public void receiveCoupon(Long id) {
        //1.根据id查询优惠券信息 做相关校验
        if (id == null){
            throw new BadRequestException("非法参数");
        }
        Coupon coupon = couponMapper.selectById(id);
        if (coupon == null) {
            throw new BadRequestException("优惠券不存在");
        }
        if (coupon.getStatus() != CouponStatus.ISSUING){
            throw new BadRequestException("优惠券不是正在发放");
        }
        //校验发放时间
        LocalDateTime now = LocalDateTime.now();
        if (now.isBefore(coupon.getIssueBeginTime()) || now.isAfter(coupon.getIssueEndTime())) {
            throw new BadRequestException("优惠券发放已经结束或尚未开始");
        }
        //校验库存
        if (coupon.getIssueNum() >= coupon.getTotalNum()) {
            throw new BadRequestException("优惠券库存不足");
        }
        //校验每人限领数量  统计当前用户对当前优惠券的已经领取的数量
        Long userId = UserContext.getUser();

        //通过redisson实现分布式锁
        */
/*String key = "lock:coupon:uid:"+userId;
        RLock lock = redissonClient.getLock(key);
        try {
            boolean isLock = lock.tryLock();
            if (!isLock){
                throw new BizIllegalException("操作频繁");
            }
            //从aop上下文中 获取当前类的代理对象
            IUserCouponService userCouponServiceProxy = (IUserCouponService)AopContext.currentProxy();
            //checkAndCreateUserCoupon(userId,coupon,null);//这种写法是调用原对象
            userCouponServiceProxy.checkAndCreateUserCoupon(userId,coupon,null);//调用代理对象的方法，方法是事务处理的
        }finally {
            lock.unlock();
        }*//*



        //从aop上下文中 获取当前类的代理对象
        IUserCouponService userCouponServiceProxy = (IUserCouponService)AopContext.currentProxy();
        //checkAndCreateUserCoupon(userId,coupon,null);//这种写法是调用原对象
        userCouponServiceProxy.checkAndCreateUserCoupon(userId,coupon,null);//调用代理对象的方法，方法是事务处理的
    }


    //保存用户券
    private void saveUserCoupon(Coupon coupon, Long userId) {
        // 1.基本信息
        UserCoupon uc = new UserCoupon();
        uc.setUserId(userId);
        uc.setCouponId(coupon.getId());
        // 2.有效期信息
        LocalDateTime termBeginTime = coupon.getTermBeginTime();
        LocalDateTime termEndTime = coupon.getTermEndTime();
        if (termBeginTime == null) {
            termBeginTime = LocalDateTime.now();
            termEndTime = termBeginTime.plusDays(coupon.getTermDays());
        }
        uc.setTermBeginTime(termBeginTime);
        uc.setTermEndTime(termEndTime);
        // 3.保存
        save(uc);
    }


    */
/**
     * 兑换码兑换优惠券接口
     * @param code
     *//*

    @Override
    //@Transactional
    public void exchangeCoupon(String code) {
        //1.校验code是否为空
        if (StringUtils.isBlank(code)){
            throw new BadRequestException("非法参数");
        }

        //2.解析兑换码得到自增id
        long serialNum = CodeUtil.parseCode(code);

        //3.判断兑换码是否已兑换  采用redis的bitmap结构  setbit  key  offset  1  如果返回true：代表已兑换
        boolean result = exchangeCodeService.updateExchangeCodeMark(serialNum,true);
        if (result){
            //说明兑换码已经被兑换
            throw new BadRequestException("兑换码已被使用");
        }

        try{
            //4.判断兑换码是否存在  根据自增id查询 主键查询
            ExchangeCode exchangeCode = exchangeCodeService.getById(serialNum);
            if (exchangeCode==null){
                throw new BizIllegalException("兑换码不存在");
            }

            //5.判断是否过期
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime expiredTime = exchangeCode.getExpiredTime();
            if (now.isAfter(expiredTime)){
                throw new BizIllegalException("兑换码已经过期");
            }

            //校验生成用户券
            Long userId = UserContext.getUser();
            Coupon coupon = couponMapper.selectById(exchangeCode.getExchangeTargetId());
            if (coupon==null){
                throw new BizIllegalException("优惠券不存在");
            }
            checkAndCreateUserCoupon(userId, coupon,serialNum);
        }catch (Exception e){
            //将兑换码状态重置
            exchangeCodeService.updateExchangeCodeMark(serialNum,false);
            throw e;
        }
    }

    @Transactional
    @MyLock(name = "lock:coupon:uid:#{userId}",lockType = MyLockType.RE_ENTRANT_LOCK,lockStrategy = MyLockStrategy.FAIL_FAST)
    public void checkAndCreateUserCoupon(Long userId, Coupon coupon, Long serialNum) {
        //只要两个字符串一样，intern()返回的一定是同一个对象
        //synchronized (userId.toString().intern()){
            Integer count = this.lambdaQuery()
                    .eq(UserCoupon::getUserId, userId)
                    .eq(UserCoupon::getCouponId, coupon.getId())
                    .count();
            if(count != null && count >= coupon.getUserLimit()){
                throw new BadRequestException("超出领取数量");
            }

            //2.优惠券的已发数量+1
            couponMapper.incrIssueNum(coupon.getId());

            //3.生成用户券
            saveUserCoupon(coupon, userId);

            if (serialNum != null){
                //修改兑换码状态
                exchangeCodeService.lambdaUpdate()
                        .set(ExchangeCode::getStatus, ExchangeCodeStatus.USED)
                        .set(ExchangeCode::getUserId,userId)
                        .eq(ExchangeCode::getId,serialNum)
                        .update();
            }
        //}

    }
}
*/
